﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NDepot.Manager.Base;
using NDepot.Repository.Base;
using NDepot.Repository;
using NDepot.Models;
using NDepot.Models.UI;

namespace NDepot.Manager
{
    public class ProductManager : IProductManager
    {
        private static IProductManager _ProductManager;
        private IProductRepository _ProductRepository;

        private ProductManager(IProductRepository p)
        {
            _ProductRepository = p;
        }

        public static IProductManager GetInstance()
        {
            return GetInstance(null);
        }

        public static IProductManager GetInstance(IProductRepository p) {
            if (_ProductManager != null)
                return _ProductManager;
            else
            {
                if (p == null)
                    p = new ProductRepository();

                _ProductManager = new ProductManager(p);

                return _ProductManager;
            }
        }

        #region Public Method

        public IList<ProductInput> GetAll()
        {
            IList<Product> products = _ProductRepository.GetAll();
            IList<ProductInput> pis = new List<ProductInput>();
            foreach (Product product in products)
                pis.Add(ProductToInput(product));

            return pis;
        }

        public bool IsUniqueTitle(string title)
        {
            return (_ProductRepository.GetByTitle(title) == null);
        }

        public void Insert(ProductInput pi)
        {
            _ProductRepository.Insert(InputToProduct(pi));
        }

        public ProductInput GetInputById(string id)
        {
            Product product = GetById(id);

            return ProductToInput(product);
        }

        public void Update(ProductInput pi)
        {
            _ProductRepository.Update(InputToProduct(pi));
        }

        public void Delete(string id)
        {
            _ProductRepository.Delete(_ProductRepository.GetById(Guid.Parse(id)));
        }

        public IList<ProductInput> FindProductsForSale()
        {
            IList<Product> products = _ProductRepository.FindProductsForSale();

            IList<ProductInput> pis = new List<ProductInput>();
            foreach (Product product in products)
                pis.Add(ProductToInput(product));

            return pis;
        }

        public IList<OrderInput> GetOrdersByProductId(string id)
        {
            Product product = GetById(id);
            IList<Order> orders = _ProductRepository.GetOrdersByProduct(product);

            var ois = new List<OrderInput>();
            foreach (Order order in orders)
                ois.Add(OrderToInput(order));

            return ois;
        }

        #endregion

        #region Private Method

        private ProductInput ProductToInput(Product product)
        {
            ProductInput pi = new ProductInput();
            pi.Id = product.Id.ToString();
            pi.Title = product.Title;
            pi.Description = product.Description;
            pi.ImageUrl = product.ImageUrl;
            pi.Price = product.Price;

            return pi;
        }

        private Product InputToProduct(ProductInput pi)
        {
            Product product = String.IsNullOrEmpty(pi.Id) ? new Product() : GetById(pi.Id);
            product.Title = pi.Title;
            product.Description = pi.Description;
            product.ImageUrl = pi.ImageUrl;
            product.Price = pi.Price;

            return product;
        }

        private Product GetById(Guid id)
        {
            return _ProductRepository.GetById(id);
        }

        private Product GetById(string id)
        {
            return GetById(Guid.Parse(id));
        }


        private OrderInput OrderToInput(Order order)
        {
            var oi = new OrderInput();
            oi.Id = order.Id.ToString();
            oi.Name = order.Name;
            oi.EMail = order.EMail;
            oi.Address = order.Address;
            oi.PayType = order.PayType;

            return oi;
        }

        #endregion
    }
}